<?
/**
 * <b>Application Class</b>
 *
 * This class is the main instantiation of the Gravy Framework. This class loads all classes and manages all operations for a given website. Kind of the controller ?
 *
 * @author Lars Sorhus (lars@saucecode.com.au)
 * @internal It's not recommended at all to modify this code.
 * @package gravy
 * @class application extends gravy
 */
class application extends gravy{
        /**
         * <b>Theme</b>
         *
         * Variable holds the theme (template) that will be sent to the browser.
         *
         * @var string
         */
	public $theme;

        /**
         * <b>View</b>
         *
         * Variable holds the view (page) that will be included in the theme (template) and sent to the browser.
         *
         * @var string
         */
        public $view;

        /**
         * <b>Controller</b>
         *
         * Variable holds the Controller (tasks associated with the view) that will be run before anything is published to the browser.
         *
         * @var string
         */
	public $controller;

        /**
         * <b>Error Theme</b>
         *
         * Variable holds the Error Theme to use when/if an error occurs.
         *
         * @var string
         */
	public $error_theme;

        /**
         * <b>Output Format</b>
         *
         * Variable holds the output format of the content that will be pubished. Some options include: html (default), xml, json, word, excel.
         *
         * @var string
         */
	public $format="html";

        /**
         * <b>Data Container</b>
         *
         * This variable hold an array of all data that will be available to the application.
         *
         * @var array
         */
	public $data;

        /**
         * <b>JavaScript Files Container</b>
         *
         * This variable hold an array of all JavaScript files that should be included in the HEAD of the theme (template).
         *
         * @var array
         */
	public $js_files;

        /**
         * <b>CSS Files Container</b>         
         * This variable hold an array of all CSS files that should be included in the HEAD of the theme (template).         
         * @var array
         */
	public $css_files;

	public $allowXml=false;
	
	public $xml_data;

	
	
	public $allowJson=false;
	
	/**
	* <b>json_data</b>
	* Array holding json_data
	* @var array
	*/
	public $json_data;

		
	/**
	* <b>renderer</b>
	* Renderer instance
	* @var renderer
	*/
	public $renderer;

	
	/**
	* <b>todo</b>
	*
	* @var ??
	*/
	public $pager;
		
	/**
	* <b>pageTitle</b>
	* Page title
	* @var string
	*/
	public $pageTitle="";
		
	/**
	* <b>rv</b>
	* Wrapper for $_REQUEST variable
	* @var array(objects)
	*/
	public $rv=NULL;

	
	/**
	* <b>Constructor</b>
	*
	* Call base (gravy) constructor
	* Initialize member arrays
	* Sets the format of the document
	* Load in request variables (from the url)
	* Loads theme, view and controller
	*
	* @fn __construct
	* @return void
	*/	
	function __construct(){
		parent::__construct();
		
		$this->data=array();
		
		$this->xml_data=array();
		
		$this->json_data=array();
		
		$this->js_files=array();
		
		$this->css_files=array();

		/**
		* Setup the Format of the document.		
		*/
		$this->format=(isset($_REQUEST["format"]))?$this->sanitize($_REQUEST["format"]):$this->config->default_format;
		$this->format=($this->format=="php")?"html":$this->format;
		
		/**
		* Load in the request variables.
		*/
		$this->setRequestData();
		
		/**
		* Load in the Theme, view and Controller Name from either the URL or the config file.
		*/
		$this->loadTvcDetails();

		#Set the page to the default page title, for the moment.
		$this->pageTitle=$this->config->default_page_title;
		
		/**
		* Displays logging info if required
		*/
		$this->logAdmin();
		
		$this->phpInfo();
	}

	
	/**
         * <b>setRequestData</b>
         *
         * Adds a variable to the rv (Request Variable). If rv isnt setup yet it also sets that up.
         *
         * @fn setRequestData
         * @param $name - [def=""]
         * @param $value - [def=null]
         * @return void
         */
	public function setRequestData($name="",$value=null){
		$special=array('format','PHPSESSID');
		if($this->rv==NULL){
			$this->rv=array();
			foreach($_REQUEST as $key=>$val){
				if(!in_array($key,$special)){
					if(is_array($val)){
						foreach($val as $key_2=>$val_2){
							$val[$key_2]=stripslashes($val_2);
						}
						if(array_key_exists($key,$this->rv)){
							$this->rv[$key]=array_merge($this->rv[$key],$val);
						}else{
							$this->rv[$key]=$val;
						}
					}else{
						if(array_key_exists($key,$this->rv)){
                                                    #print("<!-- $key //-->");
							if(is_array($this->rv[$key])){
								$this->rv[$key][]=$val;
							}else{
								$tmp=$this->rv[$key];
								$this->rv[$key]=array($tmp);
							}
						}else{
							$this->rv[$key]=stripslashes($val);
						}
					}
				}
			}
		}
		if(!in_array($name,$special)&&strlen($name)>0&&$value!=null){
			$this->rv[$name]=$value;
		}
		//$this->debug("rv", $this->rv);
	}
		
	/**
	* <b>loadTvcDetails</b>
	*
	*  Loads in the Theme, View and Controller
	* This information by default is specified in the Config File, but can be manipulated/changed in the URL.
	* The URL format is like so server.com/theme/path,to,view/controller/idToPass-anotherIdToPass-yetAnotherIdToPass
	*
	* @fn loadTvcDetails	
	* @return void
	*/	
	public function loadTvcDetails(){
		$uri=(strlen($_REQUEST["custom_uri"])>0)?$_REQUEST["custom_uri"]:$_SERVER['REQUEST_URI'];

		$tvc=preg_replace("/".str_replace("/","\\/",WEB_ROOT)."/","",$uri,1);
		$tvc=preg_replace("/\-/","_",$tvc); //takes care of '-'s in url
		
		$tvcs=@split("/",$tvc);
		
		#$this->debug("tvc",$tvc);
		$tvcs=@split("\?",$tvc);
		#$this->debug("tvcs",$tvcs);
		$tvcs=@split("/",$tvcs[0]);
		
		#$this->debug("tvcs",$tvcs);
		
		$theme=$view=$controller=$qs="";
		
		$c_index=-1;
		
		for($c=0;$c<count($tvcs);$c++){
			switch($c){				
				/**
				* app/constants.php:  THEMES_ROOT_DIR == 'app/themes/'
				* app/constants.php:  VIEWS_ROOT_DIR == 'app/views/'
				*
				* gravy/constants.php: TEMPLATE_EXT == 'php' 
				*
				* (strlen($theme) < 1 ) => It has not been set, is undefined
				*
				* Case 0: ValidSet => { 
				*	THEME, 
				*	VIEW, 
				*	VIEW & CONTROLLER(view/controller), 
				*	DEFAULT_VIEW & CONTROLLER(def_view/controller) 
				*	}
				*/
				case 0:  {
				
					/**
					* Check for THEME: if first tvc value exists in THEMES
					*/
					if(file_exists(THEMES_ROOT_DIR.$tvcs[$c].".".TEMPLATE_EXT)&&strlen($theme)<1){ 
						$theme=$tvcs[$c];
						$c_index=$c;						
					}
					
					/**
					* Check for VIEW: if first tvc-value exists in VIEWS
					*/
					elseif(file_exists(VIEWS_ROOT_DIR.$tvcs[$c])&&strlen($view)<1){
						$view=$tvcs[$c];
						$c_index=$c;
					}
					
					/**
					* Check for VIEW/CONTROLLER: isset($view) == true && (view exists) AND first tvc-value exists in 'app/views/$view/$controller'
					*/
					elseif(file_exists(VIEWS_ROOT_DIR.$view."/".$tvcs[$c].".".TEMPLATE_EXT)&&strlen($controller)<1){
						$controller=$tvcs[$c];
						$c_index=$c;
					}
					
					/**
					* Check for DEFAULT VIEW & CONTROLLER: exists(default_view) AND first tvc-value exists in 'app/views/$def_view/'
					*/
					elseif(file_exists(VIEWS_ROOT_DIR.$this->config->default_view."/".$tvcs[$c].".".TEMPLATE_EXT)&&strlen($controller)<1){
						$view=$this->config->default_view;
						$controller=$tvcs[$c];
						$c_index=$c;
					}
					
					/**
					* no theme / view / controller found 
					*/
					else{
					 	//do nothing
					}
					break;
				}
				
				/**
				* THEME must be set by now
				*
				* Case 1: ValidSet => { 	
				*	VIEW, 
				*	VIEW & CONTROLLER(view/controller), 
				*	DEFAULT_VIEW & CONTROLLER(def_view/controller) 
				*	}
				*/
				case 1: {
					/**
					* Check for VIEW: tvc-value exists in VIEWS
					*/
					if(file_exists(VIEWS_ROOT_DIR.$tvcs[$c])&&strlen($view)<1){
						$view=$tvcs[$c];
						$c_index=$c;
					}
					
					/**
					* Check for VIEW/CONTROLLER: isset($view) == true && (view exists) AND tvc-value exists in 'app/views/$view/$controller'
					*/					
					elseif(file_exists(VIEWS_ROOT_DIR.$view."/".$tvcs[$c].".".TEMPLATE_EXT)&&strlen($controller)<1){
						$controller=$tvcs[$c];
						$c_index=$c;
					}
					
					/**
					* Check for DEFAULT VIEW & CONTROLLER: exists(default_view) AND tvc-value exists in 'app/views/$def_view/$controller'
					*/
					elseif(file_exists(VIEWS_ROOT_DIR.$this->config->default_view."/".$tvcs[$c].".".TEMPLATE_EXT)&&strlen($controller)<1){
						$view=$this->config->default_view;
						$controller=$tvcs[$c];
						$c_index=$c;
					}
					break;
				}
				
				/**
				* THEME/VIEW must be set by now
				*
				* Case 2: ValidSet => { 
				*	VIEW & CONTROLLER(view/controller), 
				*	DEFAULT_VIEW & CONTROLLER(def_view/controller) 
				*	}
				*/
				case 2: {
					/**
					* Check for VIEW/CONTROLLER: isset($view) == true && (view exists) AND tvc-value exists in 'app/views/$view/$controller'
					*/
					if(file_exists(VIEWS_ROOT_DIR.$view."/".$tvcs[$c].".".TEMPLATE_EXT)&&strlen($controller)<1){
						$controller=$tvcs[$c];
						$c_index=$c;
					}
					break;
				}
			}
		}
		
		$this->debug("", "theme=> $theme");
		$this->debug("", "view => $view");
		$this->debug("", "controller => $controller");
		
		/**
		* If a theme/view/controller was found, check for query string values. (id's, etc)
		*/		
		if(count($tvcs)-1>$c_index){
			$qs=array_slice($tvcs,$c_index+1); //split on controller's index: c_index
			//$this->debug("qs",$qs);
		}
		
		/**
		* If theme, view, controller have not been found assign to defaults
		*/
		$theme=(strlen($theme)<1)?$this->config->default_theme:$theme;
		$view=(strlen($view)<1)?$this->config->default_view:$view;
		$controller=(strlen($controller)<1)?$this->config->default_controller:$controller;
		
		/**
		* If for some reason view/controller can't be found, assign to defaults
		*/
		if(!file_exists(VIEWS_ROOT_DIR.$view)||!file_exists(VIEWS_ROOT_DIR.$view."/".$controller.".".TEMPLATE_EXT)){
			$theme=$this->config->default_theme;
			$view=$this->config->default_view;
			$controller=$this->config->default_controller;
		}

		
		/**
		* Add query string to $rv (request var's)
		*/
		$this->setRequestData("GRAVY_QS",$qs);
		
		/**
		* Assign to this class's instance
		*/
		$this->theme=$theme;
		$this->view=$view;
		$this->controller=$controller;
		$this->error_theme=$this->config->error_theme;
		
		/**
		* Check if assigned theme exists, if not, assign default theme and raise error
		*/
		if(!file_exists(THEMES_ROOT_DIR.$this->theme.".".TEMPLATE_EXT)){
			$this->theme=$this->config->default_theme;
			$this->addError($this->ERROR_THEME_NOT_FOUND,"gravy.loadTvcDetails.themeNotFound",array("theme"=>THEMES_ROOT_DIR.$this->theme.".".TEMPLATE_EXT),FATAL_ERROR_ON_404);
		}
		
		/**
		* Check if assigned VIEW & CONTROLLER exists, if not, assign default VIEW & CONTROLLERs and raise error
		*/
		if(!file_exists(VIEWS_ROOT_DIR.$this->view)){
			$this->view=$this->config->default_view;
			$this->controller=$this->config->default_controller;
			$this->addError($this->ERROR_VIEW_NOT_FOUND,"gravy.loadTvcDetails.viewNotFound",array("view"=>VIEWS_ROOT_DIR.$this->view),FATAL_ERROR_ON_404);
		}
		
		/**
		* Check if ERROR theme exists, if not, assign currently-set theme
		*/
		if(!file_exists(THEMES_ROOT_DIR.$this->error_theme.".".TEMPLATE_EXT)){
			$this->error_theme=$this->theme;
		}
	}

	
	/**
         * <b>process</b>
         *
         * Includes the theme controller and  view controller files if they are set
         * The controller files contain functions only, which perform crucial operations
         *
         * @fn process
         * @return void
         */
	public function process(){
		/**
		* <b>themeControllerFile</b>		
		* Controller (always)contains a function only :: function theme_default(&$gravy)
		* e.g /home/cvu5r/public_html/dev/app/themes/controllers/default.php :: Sets login data, addTemplateData		
		* @var string
		*/
		$themeControllerFile=THEMES_ROOT_DIR."controllers/".$this->theme.".php";
		$this->debug("", "theme = $this->theme");
		if(file_exists($themeControllerFile)){
			$this->debug("", "theme controller exists $themeControllerFile");					
			include($themeControllerFile);			
		}
		else{
			$this->debug("", "theme controller not found $themeControllerFile");
		}
		
		/**
		* <b>viewControllerFile</b>
		* contains a function only :: function action_default(&$gravy){
		* e.g /home/cvu5r/public_html/dev/app/views/contact_us/controllers/default.php :: 
		* 
		* This action_default function in the view controller constructs the MODEL with: (new $contact)
		* - forms
		* - rules for gravy's validator
		*
		* @var string
		*/
		$viewControllerFile=VIEWS_ROOT_DIR.$this->view."/controllers/".$this->controller.".php";
		if(file_exists($viewControllerFile)){
			$this->debug("", "View Controller Found $viewControllerFile");
						
			include($viewControllerFile);		
		}else{
			$this->debug("view Controller Not Found",$viewControllerFile);
		}
	}
		
	/**
         * <b>render</b>
         *
         * @toDo rename method to something like doRenderProcess() - saves confusion with other 'render' methods
         *
         * Calls the functions defined in the controllers functions, eg: theme_default , action_default
         * 
         * Gets the renderer based on the application format 
         * Calls renderer->render() to render the application to the browser
         *
         * @fn render
         * @return void
         */
	public function render(){
		$this->hl(100);
		$this->debug("application->render()");
		
		/**
 		* checks if "theme_default" exists, and if so, call it, passing $this (gravy>>application) as argument		
 		*/
		$themeController="theme_".$this->theme;		
		$this->debug("themeController", $themeController);		
		if(function_exists($themeController)){
			call_user_func($themeController,$this);
		}else{
			$this->debug("Theme Controller Error",$themeController);
		}
				
		/**
 		* checks if "action_default" exists, and if so, call it, passing $this (gravy>>application) as argument		
 		*/
		$viewController="action_".$this->controller;
		$this->debug("viewController", $viewController);	
		if(function_exists($viewController)){
			call_user_func($viewController,$this);
		}else{
			$this->debug("View Controller Error",$viewController);
		}
		
		/**
 		* Gets a new renderer instance. htmlRenderer by default
 		*/
		$this->renderer=$this->getRenderer();
		
		/**
 		* Sets the specific sub-class instance's headers (default is htmlRenderer)
 		*/
        	$this->renderer->setHeadersForOutput();
		
		/**
 		* Perform render process
 		*/
 		$this->renderer->render();
	}	
	
	/**
         * <b>getRenderer</b>
         *
         * Creates (passing pointer to this application) and returns new instance of a renderer, it's type depending on  the application's format (member)
	 * Default type is htmlRenderer
         *
         * @fn getRenderer
         * @param $statusCode - [def=null]
         * @return void
         */
	public function getRenderer($statusCode=null){
		// Add in the various renders here
		#$this->debug("format",$this->format);
		switch($this->format){
			case "xml":
				#$this->debug("YEP- XML");
				if($this->allowXml){
					$renderer=new xmlRenderer($this);
					break;
				}

			case "json":
				#$this->debug("YEP- XML");
				if($this->allowJson){
					$renderer=new jsonRenderer($this);
					break;
				}

			case "ms-download":
                        case "word":
                        case "excel":
                        case "ms":
                                $renderer=new htmlRenderer($this); //pass instance of this
                                break;
			
			default:
				$this->format="html";
				$renderer=new htmlRenderer($this);
				break;
		}
		return($renderer);
	}
	
	/**
	* <b>renderErrorAndExit</b>
	*
	* Render an Error and Exit
	* Shows a standard error page and exits
	*
	* @fn renderErrorAndExit
	* @param $statusCode	
	* @return void
	*/	
	public function renderErrorAndExit($statusCode){
		$this->renderer->renderError($statusCode);
		exit();
	}

	/**
	* <b>addTemplateData</b>
	*
	* Add data to outgoing template data
	*
	* @fn addTemplateData
	* @param $data - [def = null] data<key,value> to be added to this->data member
	* @return void
	*/
	public function addTemplateData($data=NULL){
		if($data!==NULL){
			foreach($data as $key=>$value){
				$this->data[$key]=$value;
			}
		}
	}	
	
	/**
	* <b>getTemplateData</b>
	*
	* Prepares data by calling recurseTemplateData and then returns it
	*
	* @fn getTemplateData	
	* @return map<key,value>
	*/	
	public function getTemplateData(){
		$this->recurseTemplateData($this->data);
		return($this->data);
	}

	/**
	* <b>recurseTemplateData</b>
	*
	* Uses reflection to see if members contain method called getTemplateData and if yes, call it
	* Recursively goes down tree until data is found, and the data is then returned. 
	*
	* @fn recurseTemplateData
	* @param &$item - pointer to item where recursion should start
	* @return map<key,value>
	*/	
	public function recurseTemplateData(&$item){
		//cycle through the template data
		if(is_array($item)){
			#$this->debug("Item is Array");
			foreach($item as $tIndex=>&$tItem){
				if(get_class($tItem)){
					if(method_exists($tItem,"getTemplateData")){
						$tItem=$tItem->getTemplateData();
					}
				}else{
					$this->recurseTemplateData($tItem);
				}
			}
		}
		return($this->data);
	}

	
	/**
	* <b>addXmlData</b>
	*
	* Add data to the outgoing xml data.
	*
	* @fn addXmlData
	* @param $data - [def=null] data to be added. Type map<key,value>
	* @return void
	*/	
	public function addXmlData($data=NULL){
		if($data!==NULL){
			foreach($data as $key=>$value){
				$this->xml_data[$key]=$value;
			}
		}
	}

	/**
	* <b>getXmlData</b>
	*
	* Prepares xml data by calling recurseXmlData and then returns the data found
	*
	* @fn getXmlData	
	* @return map<key,value>
	*/	
	public function getXmlData(){
		$this->recurseXmlData($this->xml_data);
		return($this->xml_data);
	}

	
	/**
	* <b>recurseXmlData</b>
	*
	* Recursively searches for xml data from an item, returns it when found
	*
	* @fn recurseXmlData
	* @param &$item - pointer to item where recursive search starts
	* @return map<key,value>
	*/	
	public function recurseXmlData(&$item){
		//cycle through the template data
		if(is_array($item)){
			#$this->debug("Item is Array");
			foreach($item as $tIndex=>&$tItem){
				if(get_class($tItem)){
					$tItem=$tItem->getTemplateData();
					/*
					if(is_subclass_of($tItem,"model")){
						$this->debug("$tIndex is model subclass");
						#YOU NEED TO DO THIS
						$tItem=$tItem->getTemplateData();
					}else{
						$this->debug("$tIndex is model subclass",$tItem);
						$this->recurseTemplateData($tItem);
					}
					*/
				}else{
					$this->recurseXmlData($tItem);
				}
			}
		}
		return($this->xml_data);
	}

	/**
	* <b>addJsonData</b>
	*
	* Adds data to the json_data member
	*
	* @fn addJsonData
	* @param $data - [def=null] of type map<key,value>
	* @return void
	*/	
	public function addJsonData($data=NULL){
		if($data!==NULL){
			foreach($data as $key=>$value){
				$this->json_data[$key]=$value;
			}
		}
	}

	/**
	* <b>getJsonData</b>
	*
	* Prepares json data by calling recurseJsonData and returning resulting found data. Get the outgoing JSON data.
	*
	* @fn getJsonData	
	* @return map<key,val>
	*/	
	public function getJsonData(){
		$this->recurseJsonData($this->json_data);
		return($this->json_data);
	}

	
	/**
	* <b>recurseJsonData</b>
	*
	* Cycle through template data (TODO)
	*
	* @fn recurseJsonData
	* @param &$item - pointer to item to start recursing ($this->json_data)
	* @return void
	*/	
	public function recurseJsonData(&$item){
		//cycle through the template data
		if(is_array($item)){
			foreach($item as $tIndex=>&$tItem){
				if(get_class($tItem)){
					$tItem=$tItem->getTemplateData();
				}else{
					$this->recurseJsonData($tItem);
				}
			}
		}
		return($this->json_data);
	}

	
	/**
	* <b>setPageTitle</b>
	*
	* Set the page's title.
	*
	* @fn setPageTitle
	* @param $title - [def = NULL]
	* @return bool
	*/	
	public function setPageTitle($title=NULL){
		$this->pageTitle=($title===NULL)?$this->config->default_page_title:$title;
	}

		
	/**
	* <b>authenticate</b>
	*
	* Check whether the user has permission to access page, if not redirect them to the given url
	* If user should be returned to this page after login, an additional parameter is added to query string
	*
	* @fn authenticate
	* @param $loggedIn - [def = false] Whether user is logged in.
	* @param $redirect - [def = true]  If set to true, then redirect (usually the case)
	* @param $url - [def = null]  The URL to redirect to, if not set gets appointed WEB_ROOT
	* @return void
	*/	
	public function authenticate($loggedIn=false,$redirect=true,$url=NULL){
		if($url===NULL){
			$url=WEB_ROOT;
		}
		if($redirect&&!$loggedIn){
			$this->redirect($this->addToQueryString($url,array("return"=>urlencode($_SERVER['REQUEST_URI']))));
		}
		//return($result);
	}

	/**
	* <b>redirectToView</b>
	*
	* Redirect to a different view. Returns false on error:
	* ie. view / controller doesn't exist
	*
	* @fn redirectToView
	* @param $view - view to redirect to
	* @param $controller - controller to redirect to		
	* @return bool
	*/	
	public function redirectToView($view,$controller){
		$result=false;
		if(file_exists(VIEWS_ROOT_DIR."$view/$controller.".TEMPLATE_EXT)){
			$result=true;
			$this->view=$view;
			$this->controller=$controller;
			if(file_exists(VIEWS_ROOT_DIR."$view/controllers/$controller.php")){
				require_once(VIEWS_ROOT_DIR."$view/controllers/$controller.php");
				call_user_func("action_$controller",$this);
			}
		}
		return($result);
	}

	/**
	* <b>addJavaScriptFile</b>
	*
	* Adds a javascript file to be added to the template.
	*
	* @fn addJavaScriptFile
	* @param $file - file to be added
	* @return bool(true)
	*/	
	public function addJavaScriptFile($file){
		$this->js_files[]=$file;
		return(true);
	}

	
	/**
	* <b>outputJavaScriptFiles</b>
	*
	* Outputs additional page-specific JS files.
	*
	* @fn outputJavaScriptFiles	
	* @return bool(true)
	*/	
	public function outputJavaScriptFiles(){
		$cache=$this->config->CACHE;
		if(is_string($cache)){
			$cache="?$cache";
		}elseif($cache){
			$cache="?r=".rand(0,10000);
		}else{
			$cache="?r=".rand(0,10000);
		}
		for($c=0;$c<count($this->js_files);$c++){
			print("<script type=\"text/javascript\" src=\"".$this->js_files[$c].$cache."\"></script>".chr(13));
		}
		return(true);
	}

	
	/**
	* <b>addCSSFile</b>
	*
	* Adds a CSS file to be added to the template.
	*
	* @fn addCSSFile
	* @param $file - file to be added	
	* @return bool(true)
	*/	
	public function addCSSFile($file){
		$this->css_files[]=$file;
		return(true);
	}

	
	/**
	* <b>outputCSSFiles</b>
	*
	* Outputs additional page-specific CSS files.
	*
	* @fn outputCSSFiles
	* @return bool
	*/	
	public function outputCSSFiles(){
		$cache=$this->config->CACHE;
		if(is_string($cache)){
			$cache="?$cache";
		}elseif($cache){
			$cache="?r=".rand(0,10000);
		}else{
			$cache="?r=".rand(0,10000);
		}
		for($c=0;$c<count($this->css_files);$c++){
			print("<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"".$this->css_files[$c].$cache."\" />".chr(13));
		}
		return(true);
	}

	
	/**
	* <b>Log Admin</b>
	*
	* Debug the Log Files' contents.
	*
	* @fn logAdmin	
	* @return bool
	*/	
	public function logAdmin(){
		if($this->rv["viewLog"]=="please"){
			if($data=$this->logger->read()){
				print("<h1>Gravy Application Log</h1>");
				print("<pre>".stripslashes($data)."</pre>");
				exit();
			}else{
				print("<h1>Gravy Application Log Error</h1>");
				print("<p>Couldnt open the Gravy Application Log for review. File name: ".APP_LOG_FILE."</p>");
				exit();
			}
		}
		if($this->rv["newLog"]=="new"){
			if($data=$this->logger->read()){
				if($this->logger->newLog()){
					print("<h1>New Gravy Application Log Created</h1>");
					print("<pre>".stripslashes($data)."</pre>");
					exit();
				}else{
					print("<h1>New Gravy Application Log Creation Error</h1>");
					print("<p>Couldnt create a new Gravy Application Log...</p>");
					exit();
				}
			}
		}
		return(true);
	}	
		
	/**
	* <b>Email Admin</b>
	*
	* Send a message to all CORE Gravy Administrators (usually developers and very-top level administrators).
	* Returns true if successful, false otherwise
	*
	* @fn emailAdmin
	* @param $subject
	* @param $message	
	* @return bool
	*/	
	public function emailAdmin($subject="Message To Administrators",$message="This is an email to all core administrators."){
		$result=false;
		$mail=new phpmailer();
		$mail->Subject=$subject;
		$mail->Body=$message;
		$mail->From=($this->config->serverEmail["email"])?$this->config->serverEmail["email"]:"server@".$_SERVER['HTTP_HOST'];
		$mail->FromName=($this->config->serverEmail["name"])?$this->config->serverEmail["name"]:"server";
		for($c=0;$c<count($this->config->admin);$c++){
			$name=$this->config->admin[$c]["name"];
			$email=$this->config->admin[$c]["email"];
			$mail->AddAddress($email,$name);
			if(!$mail->Send()){
				$this->log("CRITICAL: Could not notify Core Administration Contact (name=$name, email=$email).");
			}
			$mail->ClearAllRecipients();
		}
		return($result);
	}
	
	/**
	* <b>PHP Info</b>
	*
	* Ouptut PHP INFO.
	*
	* @fn phpInfo	
	* @return void
	*/	
	public function phpInfo(){
		if($this->rv["phpinfo"]=="please"){
			phpinfo();
			exit();
		}
	}
}
?>
